package com.autumn.zero.authorization.web.controllers;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import com.autumn.common.api.application.dto.StringEntityDto;
import com.autumn.common.api.application.dto.input.AdvancedPageQueryInput;
import com.autumn.common.api.application.dto.input.AdvancedQueryInput;
import com.autumn.common.api.application.dto.output.IPageQueryResult;
import com.autumn.security.constants.AuthorizationConstants;
import com.autumn.util.ExceptionUtils;
import com.autumn.web.annotation.IgnoreApiResponseBody;
import com.autumn.zero.authorization.application.dto.modules.ResourcesModuleTypeDto;
import com.autumn.zero.authorization.application.dto.modules.ResourcesTypeInput;
import com.autumn.zero.authorization.application.services.IResourcesModuleAppService;
import com.autumn.zero.authorization.values.ResourcesModulePermissionTreeValue;
import com.autumn.zero.authorization.values.ResourcesModuleTreeValue;
import com.autumn.zero.authorization.values.ResourcesModuleValue;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 资源模块控制器
 * 
 * @author 老码农 2018-12-09 17:45:39
 */
@RestController
@RequestMapping("/sys/resources/module")
@Api(tags = "资源模块")
public class ResourcesModuleController {

	@Autowired
	private IResourcesModuleAppService service;

	/**
	 * 添加
	 * 
	 * @param input
	 *            输入
	 * @return
	 */
	@PostMapping("/add")
	@ApiOperation(value = "添加")
	@RequiresRoles(value = { AuthorizationConstants.SYSTEM_ROLE_SYSTEMS,
			AuthorizationConstants.SYSTEM_ROLE_ADMINISTRATORS }, logical = Logical.OR)
	public ResourcesModuleValue add(@Valid @RequestBody ResourcesModuleValue input) {
		return service.add(input);
	}

	/**
	 * 添加默认系统模块
	 * 
	 * @return
	 */
	@PostMapping("/addDefaultSystemModule")
	@ApiOperation(value = "添加默认系统模块")
	@RequiresRoles(value = { AuthorizationConstants.SYSTEM_ROLE_SYSTEMS,
			AuthorizationConstants.SYSTEM_ROLE_ADMINISTRATORS }, logical = Logical.OR)
	public boolean addDefaultSystemModule() {
		return service.addDefaultSystemModule();
	}

	/**
	 * 修改/更新
	 * 
	 * @param input
	 *            输入
	 * @return
	 */
	@PostMapping("/update")
	@ApiOperation(value = "修改/更新")
	@RequiresRoles(value = { AuthorizationConstants.SYSTEM_ROLE_SYSTEMS,
			AuthorizationConstants.SYSTEM_ROLE_ADMINISTRATORS }, logical = Logical.OR)
	public ResourcesModuleValue update(@Valid @RequestBody ResourcesModuleValue input) {
		return service.update(input);
	}

	/**
	 * 根据id删除
	 * 
	 * @param input
	 *            输入
	 * @return
	 */
	@PostMapping("/deleteById")
	@ApiOperation(value = "根据id删除")
	@RequiresRoles(value = { AuthorizationConstants.SYSTEM_ROLE_SYSTEMS,
			AuthorizationConstants.SYSTEM_ROLE_ADMINISTRATORS }, logical = Logical.OR)
	public void deleteById(@Valid @RequestBody StringEntityDto input) {
		ExceptionUtils.checkNotNullOrBlank(input.getId(), "id");
		service.deleteById(input.getId());
	}

	/**
	 * 根据id获取单条数据
	 * 
	 * @param input
	 *            输入
	 * @return
	 */
	@PostMapping("/queryById")
	@ApiOperation(value = "根据id获取单条数据")
	@RequiresRoles(value = { AuthorizationConstants.SYSTEM_ROLE_SYSTEMS,
			AuthorizationConstants.SYSTEM_ROLE_ADMINISTRATORS }, logical = Logical.OR)
	public ResourcesModuleValue queryById(@Valid @RequestBody StringEntityDto input) {
		ExceptionUtils.checkNotNullOrBlank(input.getId(), "id");
		return service.queryById(input.getId());
	}

	/**
	 * 查询列表
	 * 
	 * @param input
	 *            输入
	 * @return
	 */
	@PostMapping("/queryByList")
	@ApiOperation(value = "查询列表")
	@RequiresRoles(value = { AuthorizationConstants.SYSTEM_ROLE_SYSTEMS,
			AuthorizationConstants.SYSTEM_ROLE_ADMINISTRATORS }, logical = Logical.OR)
	public List<ResourcesModuleValue> queryByList(@Valid @RequestBody AdvancedQueryInput input) {
		return service.queryByList(input);
	}

	/**
	 * 查询资源类型列表
	 * 
	 * @return
	 */
	@PostMapping("/queryResourcesTypeList")
	@ApiOperation(value = "查询资源类型列表")
	@RequiresRoles(value = { AuthorizationConstants.SYSTEM_ROLE_SYSTEMS,
			AuthorizationConstants.SYSTEM_ROLE_ADMINISTRATORS }, logical = Logical.OR)
	public List<ResourcesModuleTypeDto> queryResourcesTypeList() {
		return service.queryResourcesTypeList();
	}

	/**
	 * 查询模块所有树
	 * 
	 * @return
	 */
	@PostMapping("/queryByAllTree")
	@ApiOperation(value = "查询模块所有树")
	public List<ResourcesModuleTreeValue> queryByAllTree() {
		return service.queryByTree();
	}

	/**
	 * 查询指定资源模块树
	 * 
	 * @return
	 */
	@PostMapping("/queryByTree")
	@ApiOperation(value = "查询指定资源模块树")
	public List<ResourcesModuleTreeValue> queryByTree(@Valid @RequestBody ResourcesTypeInput input) {
		return service.queryByTree(input.getResourcesType());
	}

	/**
	 * 查询指定资源菜单树
	 * 
	 * @return
	 */
	@PostMapping("/queryByMenuTree")
	@ApiOperation(value = "查询指定资源菜单树")
	public List<ResourcesModuleTreeValue> queryByMenuTree(@Valid @RequestBody ResourcesTypeInput input) {
		return service.queryByMenuTree(input.getResourcesType());
	}

	/**
	 * 查询模块所有权限树
	 * 
	 * @return
	 */
	@PostMapping("/queryByAllPermissionTree")
	@ApiOperation(value = "查询模块所有权限树")
	public List<ResourcesModulePermissionTreeValue> queryByAllPermissionTree() {
		return service.queryByPermissionTree();
	}

	/**
	 * 查询指定资源权限树
	 * 
	 * @return
	 */
	@PostMapping("/queryByPermissionTree")
	@ApiOperation(value = "查询指定资源权限树")
	public List<ResourcesModulePermissionTreeValue> queryByPermissionTree(
			@Valid @RequestBody ResourcesTypeInput input) {
		return service.queryByPermissionTree(input.getResourcesType());
	}

	/**
	 * 分页查询
	 * 
	 * @param input
	 *            输入
	 * @return
	 */
	@PostMapping("/queryByPageList")
	@ApiOperation(value = "分页查询")
	public IPageQueryResult<ResourcesModuleValue> queryByPageList(@Valid @RequestBody AdvancedPageQueryInput input) {
		return service.queryByPageList(input);
	}

	/**
	 * 下载到Excel
	 * 
	 * @param input
	 *            输入
	 * @throws UnsupportedEncodingException
	 */
	@PostMapping("/downloadByExcel")
	@ApiOperation(value = "下载Excel", produces = "application/octet-stream")
	@IgnoreApiResponseBody
	public StreamingResponseBody downloadByExcel(@Valid @RequestBody AdvancedQueryInput input,
			HttpServletResponse response) throws UnsupportedEncodingException {
		String fileName = URLEncoder.encode(service.getModuleName() + ".xls", "utf-8");
		response.setContentType("application/xls;charset=utf-8");
		response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
		Workbook workbook = service.exportByExcel(input);
		return outputStream -> {
			try {
				workbook.write(outputStream);
			} finally {
				outputStream.flush();
				outputStream.close();
			}
		};
	}
}
